#include "modelSoft.h"
#include <vtkAxesActor.h>
#include <ui_modelSoft.h>
#include <boxWindow.h>
#include <coneWindow.h>
#include <TorusWindow.h>
#include <cylinderWindow.h>
#include <sphereWindow.h>
#include <QToolBar>
#include <QTreeView>
#include <QMessageBox>
#include <QDockWidget>
#include <gp_Circ.hxx>
#include <gp_Elips.hxx>
#include <gp_Pln.hxx>
#include <gp_Lin2d.hxx>
#include <Geom_ConicalSurface.hxx>
#include <Geom_ToroidalSurface.hxx>
#include <Geom_CylindricalSurface.hxx>
#include <GCE2d_MakeSegment.hxx>
#include <TopoDS.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <BRepLib.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include <BRepBuilderAPI_MakePolygon.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <BRepPrimAPI_MakeCone.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <BRepPrimAPI_MakeTorus.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
#include <BRepPrimAPI_MakeRevol.hxx>
#include <BRepFilletAPI_MakeFillet.hxx>
#include <BRepFilletAPI_MakeChamfer.hxx>
#include <BRepOffsetAPI_MakePipe.hxx>
#include <BRepOffsetAPI_ThruSections.hxx>
#include <BRepAlgoAPI_Cut.hxx>
#include <BRepAlgoAPI_Fuse.hxx>
#include <BRepAlgoAPI_Common.hxx>
#include <AIS_Shape.hxx>
#include <V3d_View.hxx> 
#include <QSurfaceFormat>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkNamedColors.h>
#include <vtkProperty.h>
#include <vtkSmartPointer.h>
#include <vtkLine.h>
#include <IVtkTools_ShapeDataSource.hxx>
#include <vtkInteractorObserver.h>
#include <vtkActor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkMinimalStandardRandomSequence.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkPropPicker.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>
#include <TopoDS_HShape.hxx>
#include <brepWidget.h>
#include <Geom_Axis2Placement.hxx>
#include <vtkCylinderSource.h>
#include <vtkArrowSource.h>
#include <vtkAssembly.h>
#include "vtkTipsCoordinate.h"
#include <TransformOperationWidget.h>
#include <stretchWidget.h>
#include <RevolWidget.h>
#include <filletWidget.h>
#include <hollowWidget.h>
#include <curveWidget.h>
#include <gp_Pln.hxx>
#include <circleWidget.h>
#include <QDebug>
#include <vtkCamera.h>
#include <QFileDialog>


modelSoft::modelSoft(QWidget* parent)
    : SARibbonMainWindow(parent)
     ,ui(new Ui::modelSoftClass())
{
    ui->setupUi(this);
    vtkNew<vtkNamedColors> colors;
    myView->setInteractorStyle(vtkSmartPointer<QVTKInteractorStyle>::New());
    myView->setRenderer(vtkSmartPointer<vtkRenderer>::New());
    myView->setRenderWindow(vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New());
    
    myView->getRenderer()->SetBackground(colors->GetColor3d("LightGrey").GetData());
    //myView->getRenderer()->SetBackground(132,133,134);
    myView->getRenderWindow()->AddRenderer(myView->getRenderer());
    myView->getRenderWindow()->SetWindowName("RenderWindowNoUIFile");
    ui->vtkWidget->setRenderWindow(myView->getRenderWindow());
     
    vtkSmartPointer<IVtkTools_ShapePicker> shapePicker = vtkSmartPointer<IVtkTools_ShapePicker>::New();
    shapePicker->SetRenderer(myView->getRenderer());
    shapePicker->SetTolerance(0.005);
    myView->getInteractorStyle()->setOcctPicker(shapePicker);
    myView->getInteractorStyle()->setRenderer(myView->getRenderer());
    myView->getInteractorStyle()->setVTKRenderWindow(myView->getRenderWindow());
    myView->getInteractorStyle()->setCurrSelector(currSelector);
    myView->setRenderWindowInteractor(myView->getRenderWindow()->GetInteractor());
    myView->getRenderWindowInteractor()->SetInteractorStyle(myView->getInteractorStyle());
    myView->getRenderer()->GetActiveCamera()->SetPosition(0,0,1);
    // 点选择器所需的提示actor
    if (myView->getInteractorStyle()->tempSphereActor)
    {
        myView->getInteractorStyle()->tempSphereActor->SetVisibility(false);
    }
    else
    {
        myView->getInteractorStyle()->tempSphereActor = CreateTempSphereActor(0.02f, gp_Pnt());
        myView->getInteractorStyle()->tempSphereActor->SetVisibility(false);
        myView->getInteractorStyle()->tempSphereActor->SetPickable(false);
    }
    myView->getRenderWindow()->Render();
    m_historyManager = new historyMananger(this);
    m_storeManager = new storeManager(this);
    createCoordinate();
    createActions();
    createMenus();
}

Handle(QIVtkSelectionPipeline) modelSoft::updateCubePipelineShape(Handle(QIVtkSelectionPipeline) pipeline, CubeFeature *cubeFeature)
{ 
    //删除原pipeline
    RemovePipelineFromRenderer(pipeline);

    //创建新的pipeline
    Handle(QIVtkSelectionPipeline) newPipeline = makeBox(cubeFeature);

    return newPipeline;
}

Handle(QIVtkSelectionPipeline) modelSoft::updateConePipelineShape(Handle(QIVtkSelectionPipeline) pipeline, ConeFeature* coneFeature)
{
    //删除原pipeline
    RemovePipelineFromRenderer(pipeline);

    //创建新的pipeline
    Handle(QIVtkSelectionPipeline) newPipeline = makeCone(coneFeature);

    return newPipeline;
}

Handle(QIVtkSelectionPipeline) modelSoft::updateCylinderPipelineShape(Handle(QIVtkSelectionPipeline) pipeline, CylinderFeature* cylinderFeature)
{
    //删除原pipeline
    RemovePipelineFromRenderer(pipeline);

    //创建新的pipeline
    Handle(QIVtkSelectionPipeline) newPipeline = makeCylinder(cylinderFeature);

    return newPipeline;
}

Handle(QIVtkSelectionPipeline) modelSoft::updateSpherePipelineShape(Handle(QIVtkSelectionPipeline) pipeline, SphereFeature* sphereFeature)
{
    //删除原pipeline
    RemovePipelineFromRenderer(pipeline);

    //创建新的pipeline
    Handle(QIVtkSelectionPipeline) newPipeline = makeSphere(sphereFeature);

    return newPipeline;
}

Handle(QIVtkSelectionPipeline) modelSoft::updateTorusPipelineShape(Handle(QIVtkSelectionPipeline) pipeline, TorusFeature* torusFeature)
{
    //删除原pipeline
    RemovePipelineFromRenderer(pipeline);

    //创建新的pipeline
    Handle(QIVtkSelectionPipeline) newPipeline = makeTorus(torusFeature);

    return newPipeline;
}

void modelSoft::createCoordinate() {
    vtkAxesActor *axes = vtkAxesActor::New();
    vtkOrientationMarkerWidget *widget = vtkOrientationMarkerWidget::New();
    widget->SetOutlineColor(0.93, 0.57, 0.13);
    widget->SetOrientationMarker(axes);
    widget->SetInteractor(myView->getRenderWindow()->GetInteractor());
    //widget->SetViewport(0.0, 0.0, 0.4, 0.4);
    widget->SetEnabled(1);
    widget->InteractiveOff();
    /*vtkTipsCoordinate* coord = vtkTipsCoordinate::New();
    coord->SetRenderer(myView->getRenderer());
    coord->AddToRenderer();*/
}

void modelSoft::changeSelector(IVtk_SelectionMode mode)
{
    if (mode == SM_Vertex) {
        currSelector = currVertexSelector;
    }
    else if (mode == SM_Edge) {
        currSelector = currEdgeSelector;
    }
    else if (mode == SM_Face) {
        currSelector = currFaceSelector;
    }
    else {
        currSelector = currShapeSelector;
    }
}

void modelSoft::createActions()
{
    //File
    connect(ui->actionExit, SIGNAL(triggered()), this, SLOT(close()));
    connect(ui->actionSave, SIGNAL(triggered()), this, SLOT(onClickSaveToFile()));
    connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(onClickOpenFile()));
    connect(ui->actionNew, SIGNAL(triggered()), this, SLOT(onClickNewFile()));
   
    //Primitive
    connect(ui->actionBox, SIGNAL(triggered()), this, SLOT(onClickBoxButton()));
    connect(ui->actionCone, SIGNAL(triggered()), this, SLOT(onClickConeButton()));
    connect(ui->actionSphere, SIGNAL(triggered()), this, SLOT(onClickSphereButton()));
    connect(ui->actionCylinder, SIGNAL(triggered()), this, SLOT(onClickCylinderButton()));
    connect(ui->actionTorus, SIGNAL(triggered()), this, SLOT(onClickTorusButton()));
    connect(ui->actionCircle, SIGNAL(triggered()), this, SLOT(onClickCircleButton()));
    connect(ui->actionCurve, SIGNAL(triggered()), this, SLOT(OnClickCurveButton()));
    //View
    //connect(ui->actionFitAll, SIGNAL(triggered()), myModelSoftView, SLOT(fitAll()));
    connect(ui->actionReSet, SIGNAL(triggered()), this, SLOT(reSet()));
    connect(ui->actionParallel, SIGNAL(triggered()), this, SLOT(viewParallel()));
    connect(ui->actionPerspective, SIGNAL(triggered()), this, SLOT(viewPerspective()));
    connect(ui->actionFrontView, SIGNAL(triggered()), this, SLOT(frontView()));
    connect(ui->actionTopView, SIGNAL(triggered()), this, SLOT(topView()));
    connect(ui->actionRightView, SIGNAL(triggered()), this, SLOT(rightView()));
    connect(ui->actionLeftView, SIGNAL(triggered()), this, SLOT(leftView()));
    connect(ui->actionBottomView, SIGNAL(triggered()), this, SLOT(bottomView()));
    connect(ui->actionBackView, SIGNAL(triggered()), this, SLOT(backView()));

    //Pick
    connect(ui->actionCancelPick, SIGNAL(triggered()), this, SLOT(onClickCancelPickButton()));
    connect(ui->actionPickPoint, SIGNAL(triggered()), this, SLOT(OnClickPickVertexButton()));
    connect(ui->actionPickFace, SIGNAL(triggered()), this, SLOT(OnClickPickFaceButton()));
    connect(ui->actionPickLine, SIGNAL(triggered()), this, SLOT(OnClickPickLineButton()));
    connect(ui->actionPickShape, SIGNAL(triggered()), this, SLOT(OnClickPickShapeButton()));

    //Modeling
    connect(ui->actionBrep, SIGNAL(triggered()), this, SLOT(OnClickBrepButton()));
    connect(ui->actionTransform, SIGNAL(triggered()), this, SLOT(OnClickTransformButton()));
    connect(ui->actionStretch, SIGNAL(triggered()), this, SLOT(OnClickStretchButton()));
    connect(ui->actionRevol, SIGNAL(triggered()), this, SLOT(OnClickRevolButton()));
    connect(ui->actionFillet, SIGNAL(triggered()), this, SLOT(OnClickFilletButton()));
    connect(ui->actionHollow, SIGNAL(triggered()), this, SLOT(OnClickHollowButton()));
    
    //ToolBar
    connect(ui->actionUndo, SIGNAL(triggered()), this, SLOT(onUndo()));
    connect(ui->actionRedo, SIGNAL(triggered()), this, SLOT(onRedo()));
    connect(ui->actionExpression, SIGNAL(triggered()), this, SLOT(onExpression()));
}

//创建点选择器所需Actor
vtkSmartPointer<vtkActor> modelSoft::CreateTempSphereActor(float radius, const gp_Pnt& position)
{
    // 创建球形数据源
    vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
    sphereSource->SetCenter(position.X(), position.Y(), position.Z()); // 设置球心位置
    sphereSource->SetRadius(radius);           // 设置球半径
    sphereSource->Update();

    // 创建球形Mapper
    vtkSmartPointer<vtkPolyDataMapper> sphereMapper =
        vtkSmartPointer<vtkPolyDataMapper>::New();
    sphereMapper->SetInputConnection(sphereSource->GetOutputPort());

    // 创建球形Actor
    vtkSmartPointer<vtkActor> sphereActor = vtkSmartPointer<vtkActor>::New();
    sphereActor->SetMapper(sphereMapper);

    // 设置Actor的颜色
    sphereActor->GetProperty()->SetColor(1.0, 0.0, .0); // 红色

    myView->getRenderer()->AddActor(sphereActor);
    myView->getRenderWindow()->Render();

    return sphereActor;
}

void modelSoft::onClickCancelPickButton() {
    //myView->getInteractorStyle()->setOcctPickerEnabled(true);
    currSelector->clearSelectedShape();
    myView->getInteractorStyle()->setSelectionMode(SM_None);
    
}

void modelSoft::OnClickPickLineButton() {
    myView->getInteractorStyle()->setSelectionMode(SM_Edge);
    currSelector = currEdgeSelector;
    myView->getInteractorStyle()->setCurrSelector(currEdgeSelector);
}

void modelSoft::OnClickPickVertexButton() {
    myView->getInteractorStyle()->setSelectionMode(SM_Vertex);
    currSelector = currVertexSelector;
    myView->getInteractorStyle()->setCurrSelector(currVertexSelector);
    
}

void modelSoft::OnClickPickFaceButton() {
    myView->getInteractorStyle()->setSelectionMode(SM_Face);
    currSelector = currFaceSelector;
    myView->getInteractorStyle()->setCurrSelector(currFaceSelector);
}

void modelSoft::OnClickPickShapeButton() {
    myView->getInteractorStyle()->setSelectionMode(SM_Solid);
    currSelector = currShapeSelector;
    myView->getInteractorStyle()->setCurrSelector(currShapeSelector);
}

void modelSoft::OnClickBrepButton()
{
    //唤起新窗口
    brepWidget* myBrepWindow = new brepWidget(this);
    myBrepWindow->setWindowTitle("BrepOpration");
    myBrepWindow->setWindowModality(Qt::NonModal);
    myBrepWindow->setAttribute(Qt::WA_DeleteOnClose, true);
    myBrepWindow->setWindowFlags(myBrepWindow->windowFlags() | Qt::WindowStaysOnTopHint);

    myBrepWindow->show();
}

void modelSoft::OnClickTransformButton()
{
    //唤起新窗口
    TransformOperationWidget* myTransWindow = new TransformOperationWidget(this);
    myTransWindow->setWindowTitle("TransformOperation");
    myTransWindow->setWindowModality(Qt::NonModal);
    myTransWindow->setAttribute(Qt::WA_DeleteOnClose, true);
    myTransWindow->setWindowFlags(myTransWindow->windowFlags() | Qt::WindowStaysOnTopHint);

    myTransWindow->show();
}

void modelSoft::createMenus()
{

}

void modelSoft::onClickBoxButton() {
    //唤起新窗口
    CubeFeature* cubeFeature = new CubeFeature();
    cubeFeature->setLocation(gp_Pnt(0, 0, 0));
    cubeFeature->setShapeId(shapeTag++);
    cubeFeature->setLength(1);
    cubeFeature->setWidth(1);
    cubeFeature->setHigh(1);
    boxWindow* myBoxWindow = new boxWindow(this, cubeFeature);
    myBoxWindow->setWindowTitle("makeBox");
    myBoxWindow->setWindowModality(Qt::NonModal);
    myBoxWindow->setAttribute(Qt::WA_DeleteOnClose, true);
    myBoxWindow->setWindowFlags(myBoxWindow->windowFlags() | Qt::WindowStaysOnTopHint);

    myBoxWindow->show();
}

void modelSoft::onClickConeButton() {
    ConeFeature* coneFeature = new ConeFeature();
    coneFeature->setLocation(gp_Pnt(0, 0, 0));
    coneFeature->setShapeId(shapeTag++);
    coneFeature->setRadius1(1);
    coneFeature->setRadius2(0);
    coneFeature->setHigh(1);
    //唤起新窗口
    coneWindow* myConeWindow = new coneWindow(this,coneFeature);
    myConeWindow->setWindowTitle("makeCone");
    myConeWindow->setWindowModality(Qt::NonModal);
    myConeWindow->setAttribute(Qt::WA_DeleteOnClose, true);
    myConeWindow->setWindowFlags(myConeWindow->windowFlags() | Qt::WindowStaysOnTopHint);
    myConeWindow->show();
}

void modelSoft::onClickCylinderButton() {
    //!保存特征
    CylinderFeature* cylinderFeature = new CylinderFeature();
    cylinderFeature->setLocation(gp_Pnt(0, 0, 0));
    cylinderFeature->setShapeId(shapeTag++);
    cylinderFeature->setRadius1(1);
    cylinderFeature->setHigh(1);
    //唤起新窗口
    cylinderWindow* myCylinderWindow = new cylinderWindow(this,cylinderFeature);
    myCylinderWindow->setWindowTitle("makeCylinder");
    myCylinderWindow->setWindowModality(Qt::NonModal);
    myCylinderWindow->setAttribute(Qt::WA_DeleteOnClose, true);
    myCylinderWindow->setWindowFlags(myCylinderWindow->windowFlags() | Qt::WindowStaysOnTopHint);
    myCylinderWindow->show();
}

void modelSoft::onClickTorusButton() {
    //!保存特征
    TorusFeature* torusFeature = new TorusFeature();
    torusFeature->setLocation(gp_Pnt(0, 0, 0));
    torusFeature->setShapeId(shapeTag++);
    torusFeature->setRadius1(1);
    torusFeature->setRadius2(0.3);
    //唤起新窗口
    torusWindow* myTorusWindow = new torusWindow(this,torusFeature);
    myTorusWindow->setWindowTitle("makeTorus");
    myTorusWindow->setWindowModality(Qt::NonModal);
    myTorusWindow->setAttribute(Qt::WA_DeleteOnClose, true);
    myTorusWindow->setWindowFlags(myTorusWindow->windowFlags() | Qt::WindowStaysOnTopHint);
    myTorusWindow->show();
}

void modelSoft::onClickCircleButton()
{
    //唤起新窗口
    circleWidget* myCircleWindow = new circleWidget(this);
    myCircleWindow->setWindowTitle("makeCircle");
    myCircleWindow->setWindowModality(Qt::NonModal);
    myCircleWindow->setAttribute(Qt::WA_DeleteOnClose, true);
    myCircleWindow->setWindowFlags(myCircleWindow->windowFlags() | Qt::WindowStaysOnTopHint);
    myCircleWindow->show();
}

void modelSoft::OnClickStretchButton()
{
    //唤起新窗口
    stretchWidget* myStretchWindow = new stretchWidget(this);
    myStretchWindow->setWindowTitle("stretchWidget");
    myStretchWindow->setWindowModality(Qt::NonModal);
    myStretchWindow->setAttribute(Qt::WA_DeleteOnClose, true);
    myStretchWindow->setWindowFlags(myStretchWindow->windowFlags() | Qt::WindowStaysOnTopHint);
    myStretchWindow->show();
}

void modelSoft::OnClickRevolButton()
{
    //唤起新窗口
    RevolWidget* myRevolWindow = new RevolWidget(this);
    myRevolWindow->setWindowTitle("revolWidget");
    myRevolWindow->setWindowModality(Qt::NonModal);
    myRevolWindow->setAttribute(Qt::WA_DeleteOnClose, true);
    myRevolWindow->setWindowFlags(myRevolWindow->windowFlags() | Qt::WindowStaysOnTopHint);
    myRevolWindow->show();
}

void modelSoft::OnClickFilletButton()
{
    //唤起新窗口
    filletWidget* myFilletWindow = new filletWidget(this);
    myFilletWindow->setWindowTitle("filletWidget");
    myFilletWindow->setWindowModality(Qt::NonModal);
    myFilletWindow->setAttribute(Qt::WA_DeleteOnClose, true);
    myFilletWindow->setWindowFlags(myFilletWindow->windowFlags() | Qt::WindowStaysOnTopHint);
    myFilletWindow->show();
}

void modelSoft::OnClickHollowButton()
{
    //唤起新窗口
    hollowWidget* myHollowWindow = new hollowWidget(this);
    myHollowWindow->setWindowTitle("hollowWidget");
    myHollowWindow->setWindowModality(Qt::NonModal);
    myHollowWindow->setAttribute(Qt::WA_DeleteOnClose, true);
    myHollowWindow->setWindowFlags(myHollowWindow->windowFlags() | Qt::WindowStaysOnTopHint);
    myHollowWindow->show();
}

void modelSoft::OnClickCurveButton()
{

    //唤起新窗口
    curveWidget* myCurveWindow = new curveWidget(this);
    myCurveWindow->setWindowTitle("curveWidget");
    myCurveWindow->setWindowModality(Qt::NonModal);
    myCurveWindow->setAttribute(Qt::WA_DeleteOnClose, true);
    myCurveWindow->setWindowFlags(myCurveWindow->windowFlags() | Qt::WindowStaysOnTopHint);
    myCurveWindow->show();
    
}

void modelSoft::reSet()
{
    myView->getRenderer()->ResetCamera();
    //myView->getRenderer()->GetActiveCamera()->SetPosition(0, 0, 1);
    //渲染器重渲染
    myView->getRenderWindow()->Render();
}

void modelSoft::viewPerspective()
{
    //更改为透视投影
    myView->getRenderer()->GetActiveCamera()->SetParallelProjection(false);
    //渲染器重渲染
    myView->getRenderWindow()->Render();
}

void modelSoft::viewParallel()
{
    //更改为正交投影
    myView->getRenderer()->GetActiveCamera()->ParallelProjectionOn();
    //渲染器重渲染
    myView->getRenderWindow()->Render();
}

//1:front 2:back 3:right 4:left 5:top 6:bottom
void modelSoft::switchViewOrientation(int orientation)
{
    bool parallel = false;
    if (myView->getRenderer()->GetActiveCamera()->GetParallelProjection() == 1) {
        //正交投影
        parallel = true;
        //myView->getRenderer()->GetActiveCamera()->ParallelProjectionOn();
    }

    if (myView->getRenderer()->GetActiveCamera()) {
        vtkNew<vtkCamera> camera;
        switch (orientation) {
        case 3: {
            camera->SetPosition(1, 0, 0);
            break;
        }
        case 4: {
            camera->SetPosition(-1, 0, 0);
            break;
        }
        case 1: {
            camera->SetPosition(0, 0, 1);
            break;
        }
        case 5: {
            camera->SetPosition(0, 1, 0);
            break;
        }
        case 6: {
            camera->SetPosition(0, -1, 0);
            break;
        }
        case 2: {
            camera->SetPosition(0, 0, -1);
            break;
        }
        }
        camera->SetViewUp(0, 1, 0);
        camera->SetFocalPoint(0, 0, 0);
        myView->getRenderer()->SetActiveCamera(camera);
        myView->getRenderer()->ResetCamera();
        if (parallel) {
            myView->getRenderer()->GetActiveCamera()->ParallelProjectionOn();
        }
        myView->getRenderWindow()->Render();
    }
}


void modelSoft::onUndo()
{
    m_historyManager->undo();
}

void modelSoft::onRedo()
{
    m_historyManager->redo();
}

void modelSoft::onExpression()
{
    //唤起新窗口
    m_expressionWidget = new expressionWidget(this);
    m_expressionWidget->setWindowTitle("expression");
    m_expressionWidget->setWindowModality(Qt::NonModal);
    m_expressionWidget->setAttribute(Qt::WA_DeleteOnClose, true);
    m_expressionWidget->setWindowFlags(m_expressionWidget->windowFlags() | Qt::WindowStaysOnTopHint);
    m_expressionWidget->show();
}

void modelSoft::onClickSaveToFile()
{
    QString s = QFileDialog::getSaveFileName(this,
        "保存",
        "/Occ-CAD/modelSoft",
        "配置文件 (*.ini)");
    m_storeManager->saveToFile(s.toStdString());
}

void modelSoft::onClickOpenFile()
{
    QString s = QFileDialog::getOpenFileName(this, 
                         "选择要打开的文件",
                         "/Occ-CAD/modelSoft",
                         "配置文件 (*.ini)");
    qDebug() << "path=" << s;
    m_storeManager->stringToFeature(s.toStdString());
    myView->getRenderWindow()->Render();
}

void modelSoft::onClickNewFile()
{
    modelSoft* mainWindow2 = new modelSoft();
    mainWindow2->show();
}

void modelSoft::onClickSphereButton() {
    //!保存特征
    SphereFeature* sphereFeature = new SphereFeature();
    sphereFeature->setLocation(gp_Pnt(0,0,0));
    sphereFeature->setShapeId(shapeTag++);
    sphereFeature->setRadius1(1);
    //唤起新窗口
    sphereWindow* mySphereWindow = new sphereWindow(this,sphereFeature);
    mySphereWindow->setWindowTitle("makeSphere");
    mySphereWindow->setWindowModality(Qt::NonModal);
    mySphereWindow->setAttribute(Qt::WA_DeleteOnClose, true);
    mySphereWindow->setWindowFlags(mySphereWindow->windowFlags() | Qt::WindowStaysOnTopHint);
    mySphereWindow->show();
}

Handle(QIVtkSelectionPipeline) modelSoft::makeLine(const gp_Pnt& pos1, const gp_Pnt& pos2) {
    

    vtkNew<vtkNamedColors> colors;

    //const TopoDS_Edge& edgeShape = BRepBuilderAPI_MakeEdge(pos1, pos2).Edge();
    BRepBuilderAPI_MakeEdge edgeShape(pos1, pos2);
    QIVtkSelectionPipeline* edgePipeLine = new QIVtkSelectionPipeline(edgeShape, shapeTag++);
    edgePipeLine->AddToRenderer(myView->getRenderer());
    myView->getInteractorStyle()->addPipeline(edgePipeLine, edgePipeLine->GetShapeID());
    auto type = edgePipeLine->getShape().ShapeType();
    edgePipeLine->Actor()->GetProperty()->SetLineWidth(edgePipeLine->Actor()->GetProperty()->GetLineWidth() + 3);
    myView->getRenderWindow()->Render();
    return edgePipeLine;
    ////使用vtk通过确定两点坐标来绘制一条直线
    //double point1[] = {pos1.X(),pos1.Y(),pos1.Z()};
    //double point2[] = {pos2.X(),pos2.Y(),pos2.Z()};
    ////创建起始点和终点
    //vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
    //points->InsertNextPoint(point1);
    //points->InsertNextPoint(point2);
    ////创建线
    //vtkSmartPointer<vtkLine> lineSource = vtkSmartPointer<vtkLine>::New();
    ////setId为指定的点设置索引
    //lineSource->GetPointIds()->SetId(0,0);
    //lineSource->GetPointIds()->SetId(1,1);
    //
    ////创建Cell
    //vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
    //lines->InsertNextCell(lineSource);

    ////创建polydata对象
    //vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
    //polyData->SetPoints(points);
    //polyData->SetLines(lines);
    ////create mapper
    //vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    //mapper->SetInputData(polyData);

    ////create actor
    //vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
    //actor->GetProperty()->SetColor(colors->GetColor4d("Black").GetData());
    //actor->SetMapper(mapper);

    //myView->getRenderer()->AddActor(actor);
    ////渲染器重渲染
    //myView->getRenderWindow()->Render();

}


Handle(QIVtkSelectionPipeline) modelSoft::makeBox(CubeFeature* cubeFeature)
{
    //立方体资源
    BRepPrimAPI_MakeBox mybox(cubeFeature->getLocation(), cubeFeature->getLength(), cubeFeature->getWidth(), cubeFeature->getHigh());
    const TopoDS_Shape& cubeShape = mybox.Shape();
    QIVtkSelectionPipeline* cubePipeLine = new QIVtkSelectionPipeline(cubeShape, cubeFeature->getShapeId());
    cubePipeLine->AddToRenderer(myView->getRenderer());
    myView->getInteractorStyle()->addPipeline(cubePipeLine, cubePipeLine->GetShapeID());
    //将特征加入map
    auto iter1 = m_Features.find(cubeFeature->getShapeId());
    if (iter1 == m_Features.end()) {
    m_Features.insert(std::pair<Standard_Integer, CubeFeature*>(cubeFeature->getShapeId(), cubeFeature));
    }
    m_pipelineMap.insert(std::pair<Standard_Integer, QIVtkSelectionPipeline*>(cubeFeature->getShapeId(), cubePipeLine));

    myView->getRenderWindow()->Render();
    //m_operationList.
    return cubePipeLine;
    ////建立occ资源和vtk渲染器之间的通道
    //vtkNew<IVtkTools_ShapeDataSource> occSource;
    //occSource->SetShape(new IVtkOCC_Shape(shape));
    //vtkNew<vtkNamedColors> colors;
    ////映射器
    //vtkNew<vtkPolyDataMapper> boxMapper;
    //boxMapper->SetInputConnection(occSource->GetOutputPort());
    ////演员
    //vtkNew<vtkActor> boxActor;
    //boxActor->SetMapper(boxMapper);
    //boxActor->GetProperty()->SetColor(colors->GetColor4d("RoyalBlue").GetData());
    //IVtkTools_ShapeObject::SetShapeSource(occSource, boxActor);
    //renderer->AddActor(boxActor);
    ////渲染器重渲染
    //renderWindow->Render();
}


Handle(QIVtkSelectionPipeline) modelSoft::makeCone(ConeFeature* coneFeature)
{
    gp_Ax2 anAxis;
    anAxis.SetLocation(coneFeature->getLocation());
    //Occ资源
    BRepPrimAPI_MakeCone myCone(anAxis, coneFeature->getRadius1(), coneFeature->getRadius2(), coneFeature->getHigh());
    const TopoDS_Shape& coneShape = myCone.Shape();
    QIVtkSelectionPipeline* conePipeLine = new QIVtkSelectionPipeline(coneShape, coneFeature->getShapeId());
    conePipeLine->AddToRenderer(myView->getRenderer());
    
    myView->getInteractorStyle()->addPipeline(conePipeLine, conePipeLine->GetShapeID());
    //将特征加入map
    //m_coneFeatures.insert(std::pair<Standard_Integer, ConeFeature*>(coneFeature->getShapeId(), coneFeature));
    m_Features.insert(std::pair<Standard_Integer, ConeFeature*>(coneFeature->getShapeId(), coneFeature));
    m_pipelineMap.insert(std::pair<Standard_Integer, QIVtkSelectionPipeline*>(coneFeature->getShapeId(), conePipeLine));

    myView->getRenderWindow()->Render();
    return conePipeLine;
   

}

Handle(QIVtkSelectionPipeline) modelSoft::makeSphere(SphereFeature* sphereFeature)
{
    gp_Ax2 anAxis;
    anAxis.SetLocation(sphereFeature->getLocation());
    //Occ资源
    BRepPrimAPI_MakeSphere mySphere(anAxis, sphereFeature->getRadius1());
    const TopoDS_Shape& sphereShape = mySphere.Shape();
    QIVtkSelectionPipeline* spherePipeLine = new QIVtkSelectionPipeline(sphereShape, sphereFeature->getShapeId());
    spherePipeLine->AddToRenderer(myView->getRenderer());
    myView->getInteractorStyle()->addPipeline(spherePipeLine, spherePipeLine->GetShapeID());
    //将特征加入map
    //m_sphereFeatures.insert(std::pair<Standard_Integer, SphereFeature*>(sphereFeature->getShapeId(), sphereFeature));
    m_Features.insert(std::pair<Standard_Integer, SphereFeature*>(sphereFeature->getShapeId(), sphereFeature));
    m_pipelineMap.insert(std::pair<Standard_Integer, QIVtkSelectionPipeline*>(sphereFeature->getShapeId(), spherePipeLine));

    myView->getRenderWindow()->Render();
    return spherePipeLine;

}

Handle(QIVtkSelectionPipeline) modelSoft::makeCylinder(CylinderFeature* cylinderFeature)
{
    gp_Ax2 anAxis;
    anAxis.SetLocation(cylinderFeature->getLocation());
    vtkNew<vtkNamedColors> colors;
    //Occ资源
    BRepPrimAPI_MakeCylinder myCylinder(anAxis, cylinderFeature->getRadius1(), cylinderFeature->getHigh());
    const TopoDS_Shape& cylinderShape = myCylinder.Shape();
    QIVtkSelectionPipeline* cylinderPipeLine = new QIVtkSelectionPipeline(cylinderShape, cylinderFeature->getShapeId());
    cylinderPipeLine->AddToRenderer(myView->getRenderer());
    myView->getInteractorStyle()->addPipeline(cylinderPipeLine, cylinderPipeLine->GetShapeID());
    //将特征加入map
    //m_cylinderFeatures.insert(std::pair<Standard_Integer, CylinderFeature*>(cylinderFeature->getShapeId(), cylinderFeature));
    m_Features.insert(std::pair<Standard_Integer, CylinderFeature*>(cylinderFeature->getShapeId(), cylinderFeature));
    m_pipelineMap.insert(std::pair<Standard_Integer, QIVtkSelectionPipeline*>(cylinderFeature->getShapeId(), cylinderPipeLine));
    myView->getRenderWindow()->Render();
    return cylinderPipeLine;
}

Handle(QIVtkSelectionPipeline) modelSoft::makeTorus(TorusFeature* torusFeature)
{
    gp_Ax2 anAxis;
    anAxis.SetLocation(torusFeature->getLocation());
    //Occ资源
    BRepPrimAPI_MakeTorus myTorus(anAxis, torusFeature->getRadius1(), torusFeature->getRadius2());
    const TopoDS_Shape& torusShape = myTorus.Shape();
    QIVtkSelectionPipeline* torusPipeLine = new QIVtkSelectionPipeline(torusShape, torusFeature->getShapeId());
    torusPipeLine->AddToRenderer(myView->getRenderer());
    myView->getInteractorStyle()->addPipeline(torusPipeLine, torusPipeLine->GetShapeID());
    //将特征加入map
    //m_torusFeatures.insert(std::pair<Standard_Integer, TorusFeature*>(torusFeature->getShapeId(), torusFeature));
    m_Features.insert(std::pair<Standard_Integer, TorusFeature*>(torusFeature->getShapeId(), torusFeature));
    m_pipelineMap.insert(std::pair<Standard_Integer, QIVtkSelectionPipeline*>(torusFeature->getShapeId(), torusPipeLine));
    myView->getRenderWindow()->Render();
    return torusPipeLine;
    //gp_Ax2 anAxis;
    //anAxis.SetLocation(pos);
    ////圆环资源
    //BRepPrimAPI_MakeTorus myTorus(anAxis, r1, r2);
    //const TopoDS_Shape& shape = myTorus.Shape();
    ////建立occ资源和vtk渲染器之间的通道
    //vtkNew<IVtkTools_ShapeDataSource> occSource;
    //occSource->SetShape(new IVtkOCC_Shape(shape));
    //vtkNew<vtkNamedColors> colors;
    ////映射器
    //vtkNew<vtkPolyDataMapper> torusMapper;
    //torusMapper->SetInputConnection(occSource->GetOutputPort());
    ////演员
    //vtkNew<vtkActor> torusActor;
    //torusActor->SetMapper(torusMapper);
    //torusActor->GetProperty()->SetColor(colors->GetColor4d("Yellow").GetData());
    //myView->getRenderer()->AddActor(torusActor);
    ////渲染器重渲染
    //myView->getRenderWindow()->Render();

}

void modelSoft::RemovePipelineFromRendererById(Standard_Integer id)
{
    auto iter = m_pipelineMap.find(id);
    if (iter == m_pipelineMap.end()) {
        return;
    }
    Handle(QIVtkSelectionPipeline) pipeline = iter->second;
    if (!pipeline)
    {
        return;
    }
    //myView->getInteractorStyle()->deletePipelineFromMap();
    if (currSelector) {
        currSelector->deleteSelectedShape(pipeline->getShape());
    }
    m_pipelineMap.erase(pipeline->GetShapeID());
    pipeline->RemoveFromRenderer(myView->getRenderer());
    myView->getInteractorStyle()->removePipeline(pipeline->GetShapeID());
    ////释放Handle对象的内存
    //free(&pipeline);
    myView->getRenderWindow()->Render();
}

void modelSoft::RemovePipelineFromRenderer(Handle(QIVtkSelectionPipeline) pipeline)
{
    if (!pipeline)
    {
        return;
    }
    //myView->getInteractorStyle()->deletePipelineFromMap();
    if (currSelector) {
        currSelector->deleteSelectedShape(pipeline->getShape());
    }
    m_pipelineMap.erase(pipeline->GetShapeID());
    pipeline->RemoveFromRenderer(myView->getRenderer());
    myView->getInteractorStyle()->removePipeline(pipeline->GetShapeID()); 
    ////释放Handle对象的内存
    //free(&pipeline);
    myView->getRenderWindow()->Render();
}

Handle(QIVtkSelectionPipeline) modelSoft::CreatePipeline(const TopoDS_Shape& shape, Standard_Integer shapeId, bool specifyId)
{
    vtkNew<vtkNamedColors> colors;
    if (shape.IsNull())
    {
        std::cout << "Warning: Shape is Null" << std::endl;
        return nullptr;
    }

    // 创建一个Pipeline
    Handle(QIVtkSelectionPipeline) pipeline;
    //是否指定ShapeId
    if (specifyId) {
        pipeline = new QIVtkSelectionPipeline(shape, shapeId);
    }
    else {
        pipeline = new QIVtkSelectionPipeline(shape, shapeTag++);
    }
     
    pipeline->AddToRenderer(myView->getRenderer());

    pipeline->Actor()->GetProperty()->SetColor(colors->GetColor4d("RoyalBlue").GetData());
    pipeline->Actor()->GetProperty()->SetOpacity(0.5);
    m_pipelineMap.insert(std::pair<Standard_Integer, Handle(QIVtkSelectionPipeline)>(pipeline->GetShapeID(), pipeline));
    myView->getInteractorStyle()->addPipeline(pipeline, pipeline->GetShapeID());

    myView->getRenderer()->Render();

    return pipeline;
}

Handle(QIVtkSelectionPipeline) modelSoft::CreatePipelineByFeature(BaseFeature* feature)
{
    Handle(QIVtkSelectionPipeline) pipeline;
    int createType = feature->getFeatureType();
    switch (createType)
    {
    case 1:
    {
        pipeline = makeBox((CubeFeature*)feature);
        
        break;
    }
    case 3:
    {
        pipeline = makeSphere((SphereFeature*)feature);
        
        break;
    }
    case 4:
    {
        pipeline = makeCylinder((CylinderFeature*)feature);
       
        break;
    }
    case 2:
    {
        pipeline = makeCone((ConeFeature*)feature);
        
        break;
    }
    case 5:
    {
        pipeline = makeTorus((TorusFeature*)feature);
        
        break;
    }
    default:
        break;
    }
    //m_pipelineMap.insert(std::pair<Standard_Integer, Handle(QIVtkSelectionPipeline)>(pipeline->GetShapeID(), pipeline));
    return pipeline;
}

void modelSoft::BrepOperation(TopoDS_Shape& resultShape, const TopoDS_Shape& shape1,const TopoDS_Shape& shape2, int op)
{

    switch (op)
    {
    case 2:
        resultShape = BRepAlgoAPI_Common(shape1, shape2);
        break;
    case 1:
        resultShape = BRepAlgoAPI_Cut(shape1, shape2);
        break;
    case 0:
        resultShape = BRepAlgoAPI_Fuse(shape1, shape2);
        break;
    }

    if (resultShape.IsNull())
    {
        QMessageBox::warning(this, "Warning", "NUll operation result!!!");
    }
    /*return resultShape;*/
}

void modelSoft::RemoveSelectedActor(Handle(QIVtkSelectionPipeline) delSelPipe)
{
    
    currSelector->deleteSelectedShape(delSelPipe->getShape());
    myView->getInteractorStyle()->SetPipeBaseProperty(delSelPipe);
    myView->getRenderWindow()->Render();
}

Handle(QIVtkSelectionPipeline) modelSoft::TransformActor(Handle(QIVtkSelectionPipeline) trsfPipeline, const gp_Trsf& transform, int resultId)
{
    TopoDS_Shape shape = trsfPipeline->getShape();
    BRepBuilderAPI_Transform transformer(shape, transform);
    Standard_Integer shapeId = trsfPipeline->GetShapeID();

    // 移除pipeline
    RemovePipelineFromRenderer(trsfPipeline);

    Handle(QIVtkSelectionPipeline) newActor = CreatePipeline(transformer.Shape(), resultId,true);
  
    myView->getRenderWindow()->Render();
    return newActor;
}



modelSoft::~modelSoft()
{}
